/**
 * <b>项目名称：</b>网络应用框架<br/>
 * <b>包    名：</b>com.hhwy.framework.persistent.impl<br/>
 * <b>文 件 名：</b>JdbcDaoSupport.java<br/>
 * <b>版本信息：</b><br/>
 * <b>日    期：</b>2014年8月13日-下午4:35:38<br/>
 * <b>Copyright (c)</b> 2014恒华伟业科技股份有限公司-版权所有<br/>
 * 
 */
package com.hhwy.framework.persistent.impl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.ibatis.mapping.SqlCommandType;
import org.mybatis.spring.SqlSessionTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import com.github.miemiedev.mybatis.paginator.domain.PageBounds;
import com.github.miemiedev.mybatis.paginator.domain.PageList;
import com.hhwy.framework.configure.ConfigHelper;
import com.hhwy.framework.datasource.DatasourceHelper;
import com.hhwy.framework.exception.ConfigException;
import com.hhwy.framework.persistent.EntityHelper;
import com.hhwy.framework.persistent.Pagination;
import com.hhwy.framework.persistent.QueryResult;
import com.hhwy.framework.persistent.SqlDao;
import com.hhwy.framework.persistent.dialect.DatabaseExt;

/**
 * <b>类 名 称：</b>JdbcDaoSupport 通过Mybatis进行数据操作<br/>
 * <b>类 描 述：</b><br/>
 * <b>创 建 人：</b>lihuiming<br/>
 * <b>修 改 人：</b>Administrator<br/>
 * <b>修改时间：</b>2014年8月13日 下午4:35:38<br/>
 * <b>修改备注：</b><br/>
 * 
 * @version 1.0.0<br/>
 * @param <E>
 */
@SuppressWarnings("rawtypes")
@Component
@Scope("singleton")
public class SqlDaoSupport<E> implements SqlDao {
	static Logger log = LoggerFactory.getLogger(SqlDaoSupport.class);
	
	@Autowired
	SqlSessionTemplate sqlSession;
	
	@Override
	public Object getOne(String sqlKey, Map params) {
		Object result = sqlSession.selectOne(sqlKey, params);
		return result;
	}

	@Override
	public Object getOne(String sqlKey, Object parameter) {
		Object result = sqlSession.selectOne(sqlKey, parameter);
		return result;
	}

	@Override
	public List get(String sqlKey, Map params) {
		List<E> ressult = sqlSession.selectList(sqlKey, params);
		return ressult;
	}
	@Override
	public List get(String sqlKey, Object parameter) {
		List<E> ressult = sqlSession.selectList(sqlKey, parameter);
		return ressult;
	}
	
	@Override
	public int save(String sqlKey, Object parameter) {
		int result = 0;
		if(parameter != null)
			result = sqlSession.insert(sqlKey, parameter);
		else 
			result = sqlSession.insert(sqlKey);
		
		return result;
	}

	@Override
	public int update(String sqlKey, Object parameter) {
		int result = 0;
		if(parameter != null)
			result = sqlSession.update(sqlKey, parameter);
		else 
			result = sqlSession.update(sqlKey);
		
		return result;
	}

	@Override
	public int delete(String sqlKey, Object parameter) {
		int result = 0;
		if(parameter != null)
			result = sqlSession.delete(sqlKey, parameter);
		else 
			result = sqlSession.delete(sqlKey);
		
		return result;
	}
	
	@Override
	public Object executeSql(String sqlKey, Object parameter) {
		SqlCommandType SqlCommandType = sqlSession.getConfiguration().getMappedStatement(sqlKey).getSqlCommandType();
		switch (SqlCommandType) {
		case SELECT:
			return sqlSession.selectList(sqlKey, parameter);
		case INSERT:
			return sqlSession.insert(sqlKey, parameter);
		case UPDATE:
			return sqlSession.update(sqlKey, parameter);
		case DELETE:
			return sqlSession.delete(sqlKey, parameter);
		default:
			throw new ConfigException("sql " + sqlKey + " 配置异常！");
		}
	}
	public QueryResult query(String sqlKey, Map parameter){
		
		PageBounds pageBounds = new PageBounds(Pagination.pageNo.get(), Pagination.pageSize.get());
		pageBounds.setContainsTotalCount(true);
		parameter = setPagingParameter(parameter);
		List<E> ressult = sqlSession.selectList(sqlKey, parameter, pageBounds);
		
		QueryResult qr = new QueryResult();
		PageList pageList = (PageList)ressult;  
		
		qr.setTotal( new Long(pageList.getPaginator().getTotalCount()));
		qr.setData(ressult);
		return qr;
	}

	/**
	 * setPagingParameter: 描述这个方法的作用<br/>
	 * @param parameter
	 * @return 
	 * Object
	 * @exception 
	 * @since  1.0.0
	*/
	private Map setPagingParameter(Map<String,Object> parameter) {
		if(parameter == null){
			parameter = new HashMap<String ,Object>();
		}
		parameter.put("dao.paging", true);
		return parameter;
	}

	public List getAllTables(){
		return getAllTables(null);
	}
	public List getAllTables(String dbName){
		if(StringUtils.isEmpty(dbName)){
			try {
				dbName = (String)getOne("commons.sql.dbName",null);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		Map<String,String> map = new HashMap<String,String>();
		map.put("dbName", dbName);
		return get("commons.sql.selectAllTables",map);
	}

	@Override
	public void insertEntityBySQL(Object entity) {
		Map<String,Object> params = new HashMap<String, Object>();
		EntityHelper eh = new EntityHelper(entity);
		params.put("insertSQL", eh.getInsert());
		params.putAll(eh.getValueMap());
		
		sqlSession.insert("commons.sql.insertEntity", params);
	}
	@Override
	public void saveEntityBySQL(Object entity) {
		Map<String,Object> params = new HashMap<String, Object>();
		EntityHelper eh = new EntityHelper(entity);
		params.put("insertSQL", eh.getInsert());
		//数据已存在时更新
		params.put("updateClause", eh.getSetClause());
		
		checkDialect(eh,params);
		
		params.putAll(eh.getValueMap());
		
		int count = sqlSession.insert("commons.sql.saveEntity", params);
		if(log.isDebugEnabled() && count >0 )
			log.debug("影响数据行数："+count);
			
	}

	 
	@Override
	public void saveExcludeNull(Object entity) {
		Map<String,Object> params = new HashMap<String, Object>();
		boolean excludeNull = true;
		EntityHelper eh = new EntityHelper(entity, excludeNull);
		params.put("insertSQL", eh.getInsert());
		//数据已存在时更新
		params.put("updateClause", eh.getSetClause());
		
		checkDialect(eh,params);
		
		params.putAll(eh.getValueMap());
		try {
			
			sqlSession.insert("commons.sql.saveEntity", params);
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}

	/**
	 * checkDialect: 检查方言，主要处理oracle与sqlserver<br/>
	 * @param eh
	 * @param params 
	 * void
	 * @exception 
	 * @since  1.0.0
	*/
	private void checkDialect(EntityHelper eh, Map<String, Object> params) {
		String dbType = DatasourceHelper.DATABASE_TYPE.toUpperCase();
		if(dbType.equals(DatabaseExt.ORACLE.toString())){
			params.put("scheme", ConfigHelper.getConfig("ds.userName"));
			params.put("columns", eh.getFields());
			params.put("values", eh.getValues());
			params.put("tableName", eh.getTableName());
			params.put("primary_id", "'"+eh.getId()+"'");
		}else if(dbType.equals(DatabaseExt.SQLSERVER.toString())){
			params.put("columns", eh.getFields());
			params.put("values", eh.getValues());
			params.put("tableName", eh.getTableName());
			params.put("primary_id", "'"+eh.getId()+"'");
		}
		
	}

	@Override
	public void updateEntityBySQL(Object entity) {
		Map<String,Object> params = new HashMap<String, Object>();
		EntityHelper eh = new EntityHelper(entity);
		params.put("updateSQL", eh.getUpdate());
		params.putAll(eh.getValueMap());
		
		sqlSession.update("commons.sql.updateEntity", params);
	}

	@Override
	public void updateExcludeNull(Object entity) {
		Map<String,Object> params = new HashMap<String, Object>();
		boolean excludeNull = true;
		EntityHelper eh = new EntityHelper(entity, excludeNull);
		params.put("updateSQL", eh.getUpdate());
		params.putAll(eh.getValueMap());
		
		sqlSession.update("commons.sql.updateEntity", params);
		
	}
	
	@Override
	public void deleteEntityBySQL(Object entity) {
		Map<String,Object> params = new HashMap<String, Object>();
		EntityHelper eh = new EntityHelper(entity);
		params.put("entityTableName", eh.getTableName());
		params.put("condition", eh.getWhereClause());
		
		sqlSession.delete("commons.sql.deleteEntity", params);
	}

	@Override
	public void deleteEntityBySQL(String id, Object entity) {
		Map<String,Object> params = new HashMap<String, Object>();
		EntityHelper eh = new EntityHelper(entity);
		params.put("entityTableName", eh.getTableName());
		params.put("condition", "id='"+id+"'");
		sqlSession.delete("commons.sql.deleteEntity", params);
	}

	


}
